﻿using System;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Xml;
using System.Text;

namespace CRM.Encryption
{
    public static class RSAEncryption
    {
        private static BigInteger D = null;
        private static BigInteger Exponent = null;
        private static BigInteger Modulus = null;

        private static void LoadPublicKey(RSACryptoServiceProvider rsa, string publicKey)
        {
            rsa.FromXmlString(publicKey);
            RSAParameters rsaParams = rsa.ExportParameters(false);
            Modulus = new BigInteger(rsaParams.Modulus);
            Exponent = new BigInteger(rsaParams.Exponent);
        }

        private static void LoadPrivateKey(RSACryptoServiceProvider rsa, string privateKey)
        {
            rsa.FromXmlString(privateKey);
            RSAParameters rsaParams = rsa.ExportParameters(true);
            D = new BigInteger(rsaParams.D);  
            Exponent = new BigInteger(rsaParams.Exponent);
            Modulus = new BigInteger(rsaParams.Modulus);
        }

        public static string PrivateEncryption(string clearText)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            try
            {                
                string privateKey = "<RSAKeyValue><Modulus>sdjRuj9QHjoLGVmaPdlYrbN0ZHbm/aPmeCpbb3npK7u02Dgzs5WzVJNg5ScPrIHxrWjS0iNiPyDh2VQ840p8pu6qZijk0einkyppYRApPdZ8MhXqvHIiu20V9KBAjqtrHTvdvg28AJ6w8qjX0XgbatFy2XyK0M4EQHi2Q04QRAk=</Modulus><Exponent>AQAB</Exponent><P>46XWbsOd4QPmqkJi3522e+kHs4bKuFB+JjHzjKWyCwwquvcZfafdL4Us0hQkj4YArk09AWZh7vk9KjVpWS2wcw==</P><Q>x/8qkFO6pyZI2iQfKz42VJoXdfgLSe2lCZllkcve7TCQiC1JYhbcktRTcojQw8C+qvybIUlXSgBmEg40NHnGkw==</Q><DP>txXVU9f3zdS5Ww1xP68z6IwOKZCq0XnLOyTJX8CTZNcwNpYs5iZveZx946dXkCaRvZ1ZBxs0gGHrk1rJk3NviQ==</DP><DQ>HsBobgrBz4O+ffRB6qdFOVr8MoJyUeq9jq1Mhc+ANp5aCuZTu0Zioh0Nu7W3y/GuH6J5w/N//Xv0NeCDPHJhCw==</DQ><InverseQ>KCKymn8FxBZrdAYu+3sSoNXFuYxG1W1H1ZvPPxGnJ4eUHcFGX9CB3jinUiTnDDYpwKGHuC7WlE/CLTGLqw40fw==</InverseQ><D>EI4Kw8gF+LJVeygck/pJ521nfbyVtvGNUA09Uqyp+FCyPlhI88QRG+PWJq6Spm+4I/i4eyghCphQfa76NfwmiymodGjGQDCrq112MfVn441nSIwqZRpwUH2QFtaoAnSt8h+5fVPUGkcDetn6oqhpBYcbZg1LuC+++7D3SReWidM=</D></RSAKeyValue>";
                LoadPrivateKey(rsa, privateKey);

                byte[] data = Encoding.UTF8.GetBytes(clearText);
                BigInteger bnData = new BigInteger(data);
                BigInteger encData = bnData.modPow(D, Modulus);
                rsa.Clear();
                return Convert.ToBase64String(encData.getBytes());
            }
            catch
            {
                rsa.Clear();
                return null;
            }
        }

        public static string PublicDecryption(string encryptedText)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            try
            {
                string publicKey = "<RSAKeyValue><Modulus>sdjRuj9QHjoLGVmaPdlYrbN0ZHbm/aPmeCpbb3npK7u02Dgzs5WzVJNg5ScPrIHxrWjS0iNiPyDh2VQ840p8pu6qZijk0einkyppYRApPdZ8MhXqvHIiu20V9KBAjqtrHTvdvg28AJ6w8qjX0XgbatFy2XyK0M4EQHi2Q04QRAk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
                LoadPublicKey(rsa, publicKey);
                byte[] encryptedData = Convert.FromBase64String(encryptedText);
                BigInteger encData = new BigInteger(encryptedData);
                BigInteger bnData = encData.modPow(Exponent, Modulus);
                rsa.Clear();
                return Encoding.UTF8.GetString(bnData.getBytes());
            }
            catch (Exception ex)
            {
                rsa.Clear();
                return null;
            }
        }
    }
}
